package com.denlaku.longan.util;

import com.denlaku.longan.SnowFlake;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;

import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author tianx
 */
public class SnowflakeUtils {
	private static final ConcurrentMap<String, SnowFlake> CACHE = new ConcurrentHashMap<>();

	private static final String DEFAULT_BIZ = "default";

	public static Long nextId() {
		return nextId(DEFAULT_BIZ);
	}

	public static Long nextId(String biz) {
		SnowFlake snowFlake = CACHE.computeIfAbsent(biz, k -> initSnowFlake());
		return snowFlake.nextId();
	}

	private static SnowFlake initSnowFlake() {
        int dataCenterId = getDataCenterId();
        int machineId = getMachineId();
        return new SnowFlake(dataCenterId, machineId);
	}

	private static int getDataCenterId() {
		List<String> ips = ServerUtil.getIps();
		String str = String.join(":", ips);
		int[] points = StringUtils.toCodePoints(str.toUpperCase(Locale.ROOT));
		int dataCenterId = 0;
		for (int point : points) {
			dataCenterId += point;
		}
		return dataCenterId & 31;
	}

	private static int getMachineId() {
		String hostName = SystemUtils.getHostName();
		int[] points = StringUtils.toCodePoints(hostName.toUpperCase(Locale.ROOT));
		int machineId = 0;
		for (int point : points) {
			machineId += point;
		}
		return machineId & 31;
	}

}
